Skip to content

Conversation

@414owen
Copy link

@414owen 414owen commented Jan 3, 2026

Closes #1577

@github-actions github-actions bot added the awaiting-review This PR is ready for review; the author thinks it is ready to be merged. label Jan 3, 2026
@fgdorais
Copy link
Collaborator

fgdorais commented Jan 6, 2026

Please add a copyright header and follow style from similar files.

@fgdorais fgdorais added awaiting-author Waiting for PR author to address issues and removed awaiting-review This PR is ready for review; the author thinks it is ready to be merged. labels Jan 6, 2026
@fgdorais fgdorais changed the title Add Alternative.{many,many1} feat: add Alternative.{many,many1} Jan 6, 2026
@414owen 414owen force-pushed the os/alternative-many branch from 7fc04f7 to 65ab39c Compare January 6, 2026 21:43
@fgdorais
Copy link
Collaborator

fgdorais commented Jan 6, 2026

I made a few minor edits, mostly so that CI works. I hope you don't mind, it was easier to do than to explain.

PS: Avoid force push.

leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Jan 6, 2026
@414owen
Copy link
Author

414owen commented Jan 6, 2026

I hope you don't mind, it was easier to do than to explain.

Absolutely fine. Be my guest.

@leanprover-community-bot
Copy link
Collaborator

leanprover-community-bot commented Jan 6, 2026

Mathlib CI status (docs):

Comment on lines +29 to +36
def many1 [Alternative f]
(p : f α) : f (Σ n, Vector α (1 + n)) :=
let g x xs := ⟨xs.1, Vector.singleton x ++ xs.2
let toVec (l : List α) : Σ n, Vector α n :=
let arr := List.toArray l
⟨arr.size, ⟨arr, rfl⟩⟩
let manyVec : f (Σ n, (Vector α n)) := toVec <$> Alternative.many p
g <$> p <*> manyVec <|> Alternative.failure
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to wait for pending Zulip discussion; but the two many1 functions in Lean already are the much simpler

Suggested change
def many1 [Alternative f]
(p : f α) : f (Σ n, Vector α (1 + n)) :=
let g x xs := ⟨xs.1, Vector.singleton x ++ xs.2
let toVec (l : List α) : Σ n, Vector α n :=
let arr := List.toArray l
⟨arr.size, ⟨arr, rfl⟩⟩
let manyVec : f (Σ n, (Vector α n)) := toVec <$> Alternative.many p
g <$> p <*> manyVec <|> Alternative.failure
def many1 [Alternative f] (p : f α) : f (List α) :=
List.cons <$> p <*> many p

in the absence of a concrete use case requiring the complexity, I'd be inclined to pick this much simpler option.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(note that independently, the <|> Alternative.failure looks like a no-op to me)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def many1 [Alternative f] (p : f α) : f (List α) :=
List.cons <$> p <*> many p

I'm not a huge fan of this version to be honest. It means that, even though you know there's at least one element, operations like head, and tail are partial.

It throws away useful information, and goes against "make error states unrepresentable" / "parse, don't validate", etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but my proposal is consistent with Std.Internal.Parsec.many1 from the standard library.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is something I can't deny :)

The design for `many1` doesn't seem very clear-cut, it's sparked quite
a bit of discourse in zulip:

https://leanprover.zulipchat.com/#narrow/channel/348111-batteries/topic/Nonempty.20List.20Type/with/567406954

Let's defer it to another PR.
@414owen
Copy link
Author

414owen commented Jan 12, 2026

Since many1 needs some thought and design put into it, I've removed it, to make this PR easier to resolve.

@414owen 414owen changed the title feat: add Alternative.{many,many1} feat: add Alternative.many Jan 12, 2026
@fgdorais
Copy link
Collaborator

Please bring back many1. Thanks!

@414owen 414owen changed the title feat: add Alternative.many feat: add Alternative.{many,many1} Jan 19, 2026
@fgdorais
Copy link
Collaborator

Please edit the lean-toolchain file to leanprover/lean4-pr-releases:pr-release-12041. That will fix the missing Nonempty instance. We can do a forward-port later if necessary.

@fgdorais fgdorais changed the base branch from main to nightly-testing January 19, 2026 10:58
@fgdorais
Copy link
Collaborator

I've rebased this PR on nightly-testing instead of main. This is of no consequence for the most part but there may be a bit more background noise. Ignore any noise that isn't related to your code and I will filter out the rest.

@fgdorais
Copy link
Collaborator

You should no longer need many.aux at this point.

Using List and List.cons the way you do means that the last alternative is the head of the list. Is that intentional? If not, I recommend using Array and Array.push. This would also be consistent with other *.many functions.

PS: I will soon be away for the next few days. Don't worry, I'll be back next week at the latest.

@414owen
Copy link
Author

414owen commented Jan 19, 2026

Using List and List.cons the way you do means that the last alternative is the head of the list. Is that intentional

Are you sure about that?

  List.cons <$> p <*> many p <|> pure []

Could be written monadically, for clarity:

def alt1 p := do
  x <- p
  xs <- many p
  pure $ List.cons x xs

...

alt1 p <|> pure []

So the first thing parsed should end up as the head of the list, unless I'm missing something?

@fgdorais
Copy link
Collaborator

I think you're right! This needs some tests to ensure this is the actual behavior.

@leanprover-community-mathlib4-bot leanprover-community-mathlib4-bot added the merge-conflict This PR has merge conflicts with the `main` branch which must be resolved by the author. label Jan 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-author Waiting for PR author to address issues builds-mathlib merge-conflict This PR has merge conflicts with the `main` branch which must be resolved by the author.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RFC: Consider adding Alternative.{many,many1}

5 participants